namespace taurus.client {

    /**
     * SystemController
     */
    export class SystemController {
        public static CONNECT_TOKE: string = "$t";
        public static CONNECT_PROT_COMPRESSION: string = "$pc";
        public static REQUEST_CMD: string = "$c";
        public static REQUEST_GID: string = "$gi";
        public static REQUEST_PARM: string = "$p";
        public static REQUEST_RESULT: string = "$r";

        /**
         * pingpong
         */
        public static ACTION_PINGPONG: number = 0;
        /**
         * 客户端请求
         */
        public static ACTION_REQUST_CMD: number = 1;
        /**
         * 服务器事件消息
         */
        public static ACTION_EVENT_CMD: number = 2;
        private _tempID: number = 0;
        private _engine: SocketEngine;
        private _handleList: Message[] = [];

        public constructor(engine: SocketEngine) {
            this._engine = engine;
        }

        private _getValidID(): number {
            return ++this._tempID;
        }

        handlePacket(packet: Packet) {
            switch (packet.actionID) {
                case SystemController.ACTION_PINGPONG:
                    this.fnPingPong(packet);
                    break;
                case SystemController.ACTION_REQUST_CMD:
                    this.fnOperationResponse(packet);
                    break;
                case SystemController.ACTION_EVENT_CMD:
                    this.fnOperationEvent(packet);
                    break;
            }
        }

        private fnOperationResponse(packet: Packet) {
            let gid = packet.parameters.getInt(SystemController.REQUEST_GID);
            let result = packet.parameters.getInt(SystemController.REQUEST_RESULT);
            let tem = null;
            if (packet.parameters.containsKey(SystemController.REQUEST_PARM)) {
                tem = packet.parameters.getTObject(SystemController.REQUEST_PARM);
            }
            let msg: Message = null;
            let index = 0;
            let len = this._handleList.length;
            if (gid > 0) {
                for (let i = 0; i < len; ++i) {
                    if (gid == this._handleList[i].gid) {
                        msg = this._handleList[i];
                        index = i;
                        break;
                    }
                }
            }

            if (msg != null) {
                if (msg.callback != null) {
                    var response = new MessageResponse();
                    if (result == 0) {
                        msg.param = tem;
                    }
                    response.messageData = msg;
                    response.returnCode = result;
                    msg.callback(response);
                }
                this._handleList.splice(index, 1);
            }

        }

        private fnOperationEvent(packet: Packet) {
            let cmd = packet.parameters.getString(SystemController.REQUEST_CMD);
            let tem = null;
            if (packet.parameters.containsKey(SystemController.REQUEST_PARM)) {
                tem = packet.parameters.getTObject(SystemController.REQUEST_PARM);
            }
            this.handleEvent(cmd, tem);

        }

        private handleEvent(cmd: string, param: ITObject) {
            let msg = new Message();
            msg.command = cmd;
            msg.param = param;
            let cb = this._engine._onEvent;
            cb.func.call(cb.thisObject, msg);
        }

        private fnPingPong(packet: Packet) {
            this._engine._lagMonitor.fnPingPong();
        }

        sendRequest(msg: Message) {
            var packet = new Packet();
            packet.actionID = SystemController.ACTION_REQUST_CMD;
            var obj = TObject.newInstance();
            obj.putString(SystemController.REQUEST_CMD, msg.command);
            if (msg.param != null) {
                obj.putTObject(SystemController.REQUEST_PARM, msg.param);
            }

            if (msg.callback != null) {
                var gid = this._getValidID();
                obj.putInt(SystemController.REQUEST_GID, gid);
                msg.gid = gid;
                this._handleList.push(msg);

            }
            packet.parameters = obj;
            this._engine._packetHandler.onDataWrite(packet);
        }

        sendPingPong() {
            var packet = new Packet();
            packet.actionID = SystemController.ACTION_PINGPONG;
            packet.parameters = TObject.newInstance();
            this._engine._packetHandler.onDataWrite(packet);
        }

    }
}